﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using HtmlAgilityPack;
using Travan.ServerServices.CustomObjects;
using Travan.ServerServices.Interfaces;

namespace Travan.ServerServices
{
    public class HttpHelpers : IHttpHelpers
    {

        #region IHttpHelpers Members

        public TravianSession Get(string url, TravianSession session)
        {
            
            Uri serveruri = new Uri(url);
            
            
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.CookieContainer = new CookieContainer();
            if (session.cookies != null && session.cookies.Count > 0)
            {
                request.CookieContainer.Add(session.cookies);
            }

            //Set Headers so that it looks like a browser
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            
            request.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
            request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
            request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-us,en;q=0.5");
            request.Headers.Add(HttpRequestHeader.KeepAlive, "115");
            
            //request.Headers.Add("Proxy-Connection", "keep-alive");
            request.UserAgent =
                "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9";
            

            using (var response = (HttpWebResponse)request.GetResponse())
            {
                //response.Cookies
                using (var stream = response.GetResponseStream())
                {
                    UpdateCookies(session, response.Cookies);
                    using (var gzipstream = new GZipStream(stream,  CompressionMode.Decompress))
                    {
                        using (var reader = new StreamReader(gzipstream))
                        {
                            var value = reader.ReadToEnd();
                            var document = new HtmlDocument();

                            document.LoadHtml(value);

                            session.CurrentDocument = document;

                            return session;
                        }
                    }
                }
            }
            
        }

        public TravianSession Post(string url, TravianSession session)
        {
            Uri serveruri = new Uri(url);


            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.CookieContainer = new CookieContainer();
            if (session.cookies != null && session.cookies.Count > 0)
            {
                request.CookieContainer.Add(session.cookies);
            }

            //Set Headers so that it looks like a browser
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

            request.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
            request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
            request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-us,en;q=0.5");
            request.Headers.Add(HttpRequestHeader.KeepAlive, "115");

            //request.Headers.Add("Proxy-Connection", "keep-alive");
            request.UserAgent =
                "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9";
            request.ContentType = "application/x-www-form-urlencoded";

            ASCIIEncoding encoding = new ASCIIEncoding();

            string postData = "";
            //Build post request
            foreach (var item in session.FormValues )
            {
                postData += item.Key + "=" + item.Value + "&";
            }

            if (session.FormValues.Count > 0) postData=postData.Remove(postData.Length - 1);

            
            byte[] data = encoding.GetBytes(postData);


            using (var requeststream = request.GetRequestStream())
            {
                requeststream.Write(data,0,data.Length);    
            }

            using (var response = (HttpWebResponse)request.GetResponse())
            {
                //response.Cookies
                using (var stream = response.GetResponseStream())
                {
                    UpdateCookies(session, response.Cookies);
                    
                    using (var gzipstream = new GZipStream(stream, CompressionMode.Decompress))
                    {
                        using (var reader = new StreamReader(gzipstream))
                        {
                            var value = reader.ReadToEnd();
                            var document = new HtmlDocument();

                            document.LoadHtml(value);

                            session.CurrentDocument = document;

                            return session;
                        }
                    }
                }
            }
            
        }

        #endregion

        #region "Private helpers"
        private void UpdateCookies(TravianSession session, CookieCollection cookies)
        {
            if (session.cookies == null)
                session.cookies = cookies;
            foreach (Cookie cookie in cookies)
            {
                
                    session.cookies.Add(cookie);
            }
        }

        #endregion
    }
}
